package org.jeecg.modules.api.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.*;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.ptUsers.entity.PtUsers;
import org.jeecg.modules.ptUsers.service.IPtUsersService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Random;

import static com.jeecg.qywx.api.base.JwParamesAPI.token;

/**
 * app对外全部接口
 */
@Slf4j
@RestController
@RequestMapping("/app/api")
public class AppUserloginApiController {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ISysDepartService sysDepartService;

    @Resource
    private BaseCommonService baseCommonService;

    @Autowired
    private SysBaseApiImpl sysBaseApi;

    @Autowired
    private IPtUsersService ptUsersService;
    /**
     * app登录
     *
     * @param jsonObject
     * @return
     * @throws Exception
     */
    @ApiOperation("app登录")
    @RequestMapping(value = "/appLogin", method = RequestMethod.POST, produces = "application/json")
    public Result<JSONObject> appLogin(@RequestBody JSONObject jsonObject) throws Exception {
        Result<JSONObject> result = new Result<JSONObject>();
        String username = jsonObject.getString("username");
        String password = jsonObject.getString("password");
        //1. 校验用户是否有效
        LambdaQueryWrapper<PtUsers> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PtUsers::getUserName,username);
        PtUsers user = ptUsersService.getOne(queryWrapper);
        result = ptUsersService.checkUserIsEffective(user);
        if(!result.isSuccess()) {
            return result;
        }
        //2. 校验用户名或密码是否正确
        String userpassword = PasswordUtil.encrypt(username, password, user.getSalt());
        String syspassword = user.getPassword();
        if (!syspassword.equals(userpassword)) {
            result.error500("用户名或密码错误");
            return result;
        }
        JSONObject obj = new JSONObject();
        //用户登录信息
        obj.put("userInfo", user);
        // 生成token
        String token = JwtUtil.sign(username, syspassword);
        // 设置超时时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
        //token 信息
        obj.put("token", token);
        result.setResult(obj);
        result.setSuccess(true);
        result.setCode(200);
        baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]！", CommonConstant.LOG_TYPE_1, null);
        return result;
    }

    /**
     * 获取验证码接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("短信验证登录...1是注册模式...2是登录模式")
    @PostMapping(value = "/sms")
    public Result<String> sms(@RequestBody JSONObject jsonObject) {
        Result<String> result = new Result<String>();
        String phone = jsonObject.getString("phone");
        //手机号模式 登录模式: "2"  注册模式: "1"
        String smscode = jsonObject.get("smscode").toString();
        log.info(phone);
        if (oConvertUtils.isEmpty(phone)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
        Object object = redisUtil.get(redisKey);
        if (object != null) {
            result.setMessage("验证码10分钟内，仍然有效！");
            result.setSuccess(false);
            return result;
        }
        //随机数
        String captcha = RandomUtil.randomNumbers(6);
        JSONObject obj = new JSONObject();
        obj.put("code", captcha);
        try {
            boolean b = false;
            //注册模板
            if (CommonConstant.SMS_TPL_TYPE_1.equals(smscode)) {
                PtUsers sysUser = ptUsersService.getUserByPhone(phone);
                if (sysUser != null) {
                    result.error500(" 手机号已经注册，请直接登录！");
                    baseCommonService.addLog("手机号已经注册，请直接登录！", CommonConstant.LOG_TYPE_1, null);
                    return result;
                }
                b = DySmsHelper.sendSms(phone, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
            } else {
                //登录模式，校验用户有效性
                PtUsers sysUser = ptUsersService.getUserByPhone(phone);
                result = ptUsersService.checkUserIsEffective(sysUser);
                if (!result.isSuccess()) {
                    String message = result.getMessage();
                    String userNotExist = "该用户不存在，请注册";
                    if (userNotExist.equals(message)) {
                        result.error500("该用户不存在或未绑定手机号");
                    }
                    return result;
                }
                /**
                 * smsmode 短信模板方式  0 .登录模板、1.注册模板、2.忘记密码模板
                 */
                if (CommonConstant.SMS_TPL_TYPE_0.equals(smscode)) {
                    //登录模板
                    b = DySmsHelper.sendSms(phone, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
                } else if (CommonConstant.SMS_TPL_TYPE_2.equals(smscode)) {
                    //忘记密码模板
                    b = DySmsHelper.sendSms(phone, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
                }
            }
            if (b == false) {
                result.setMessage("短信验证码发送失败,请稍后重试");
                result.setSuccess(false);
                return result;
            }
            redisUtil.set(redisKey, captcha, 600);
            result.setSuccess(true);
        } catch (ClientException e) {
            e.printStackTrace();
            result.error500(" 短信接口未配置，请联系管理员！");
            return result;
        }
        return result;
    }

    /**
     * 手机号登录接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("手机号登录接口")
    @PostMapping("/phoneLogin")
    public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject) {
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = jsonObject.getString("phone");
        //校验用户有效性
        PtUsers sysUser = ptUsersService.getUserByPhone(phone);
        result = ptUsersService.checkUserIsEffective(sysUser);
        if (!result.isSuccess()) {
            return result;
        }
        String smscode = jsonObject.getString("smscode");
        //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
        //Object code = redisUtil.get(redisKey);
        Object code = "123456";
        //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
        if (!smscode.equals(code)) {
            result.setMessage("手机验证码错误");
            return result;
        }
        JSONObject obj = new JSONObject();
        //用户登录信息
        obj.put("userInfo", sysUser);
        // 设置超时时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
        obj.put("token", token);
        result.setResult(obj);
        result.setSuccess(true);
        result.setCode(200);
        //添加日志
        baseCommonService.addLog("用户名: " + sysUser.getUserName() + ",登录成功！", CommonConstant.LOG_TYPE_1, null);
        return result;

    }

    /**
     * 用户注册接口
     *
     * @param jsonObject
     * @param user
     * @return
     */
    @ApiOperation("用户注册接口")
    @PostMapping("/appRegister")
    public Result<JSONObject> userRegister(@RequestBody JSONObject jsonObject,PtUsers user) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; // 输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) // 字符串
            {
                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) // 数字
            {
                val += String.valueOf(random.nextInt(10));
            }
        }
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = jsonObject.getString("phone");
        String smscode = jsonObject.getString("smscode");
        String username = jsonObject.getString("username");
        String password = jsonObject.getString("password");
//        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
//        Object code = redisUtil.get(redisKey);
        Object code = "123456";
        PtUsers sysUser1 = ptUsersService.getUserByName(username);
        if (sysUser1 != null) {
            result.setMessage("用户名已注册");
            result.setSuccess(false);
            return result;
        }
        PtUsers sysUser2 = ptUsersService.getUserByPhone(phone);
        if (sysUser2 != null) {
            result.setMessage("该手机号已注册");
            result.setSuccess(false);
            return result;
        }
        if (code == null) {
            result.setMessage("手机验证码失效，请重新获取");
            result.setSuccess(false);
            return result;
        }
            if (!smscode.equals(code)) {
                result.setMessage("手机验证码错误");
                result.setSuccess(false);
                return result;
            } else {
                try {
                    // 设置创建时间
                    user.setCreateTime(new Date());
                    String salt = oConvertUtils.randomGen(8);
                    String passwordEncode = PasswordUtil.encrypt(username, password, salt);
                    user.setSalt(salt);
                    user.setPhone(phone);
                    user.setUserName(username);
                    user.setNickname(username);
                    user.setPassword(passwordEncode);
                    user.setIsDoctor("0");
                    user.setCreateBy(username);
                    user.setUserState(String.valueOf(CommonConstant.USER_UNFREEZE));
                    ptUsersService.save(user);
                    result.success("注册成功");
                } catch (Exception e) {
                    result.error500("注册失败");
                }
            }
            return result;
    }


    /**
     * 重置密码接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("重置密码接口")
    @PostMapping("/reset_password")
    public Result<JSONObject> resetPassword(@RequestBody JSONObject jsonObject) {
        String phone = jsonObject.getString("phone");
        String smscode = jsonObject.getString("smscode");
        String password = jsonObject.getString("password");
//
//        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
//        Object code = redisUtil.get(redisKey);
        Object code = "123456";
        if (code == null) {
            return Result.OK("手机验证码失效，请重新获取");
        } else if (!smscode.equals(code)) {
                return Result.OK("手机验证码错误");
            } else {
                QueryWrapper<PtUsers> sysUserQueryWrapper = new QueryWrapper<>();
                sysUserQueryWrapper.eq("phone", phone);
                PtUsers sysUser = ptUsersService.getOne(sysUserQueryWrapper);
                String salt = oConvertUtils.randomGen(8);
                String passwordEncode = PasswordUtil.encrypt(sysUser.getUserName(), password, salt);
                sysUser.setSalt(salt);
                sysUser.setPassword(passwordEncode);
                ptUsersService.updateById(sysUser);
                return Result.OK("修改成功");
            }
    }

    /**
     * 修改密码接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("修改密码接口")
    @PostMapping("/change_password")
    public Result<JSONObject> changePassword(@RequestBody JSONObject jsonObject) {
        Result<JSONObject> result = new Result<JSONObject>();
        String userId = jsonObject.getString("userId");
        String oldpassword = jsonObject.getString("oldpassword");
        String newpassword = jsonObject.getString("newpassword");
        QueryWrapper<PtUsers> sysUserQueryWrapper=new QueryWrapper<>();
        sysUserQueryWrapper.eq("id",userId);
        PtUsers sysUser=ptUsersService.getOne(sysUserQueryWrapper);
        String salt=sysUser.getSalt();
        String passwordEncode = PasswordUtil.encrypt(sysUser.getUserName(),oldpassword,salt);
        String passwordEncode1 = PasswordUtil.encrypt(sysUser.getUserName(),newpassword,salt);
        if (passwordEncode.equals(sysUser.getPassword())) {
            String salt1 = oConvertUtils.randomGen(8);
            String passwordcode = PasswordUtil.encrypt(sysUser.getUserName(),newpassword,salt1);
            sysUser.setPassword(passwordcode);
            sysUser.setSalt(salt1);
            ptUsersService.updateById(sysUser);
            return  Result.OK("修改成功");
        } else if(passwordEncode.equals(passwordEncode1)){
            result.setMessage("新密码与旧密码相同请输入不同的密码");
            result.setSuccess(false);
            return result;
        }else {
            result.setMessage("密码不正确，请重新输入");
            result.setSuccess(false);
            return result;
        }
    }
}
